<template>
  <Modal
    v-model="showEditApiModal"
    title="编辑接口"
    :closable="false"
    fullscreen
    @on-cancel="handleEditApiCancel"
  >
    <Form
      label-position="right"
      :label-width="100"
      ref="apiForm"
      :model="apiForm"
      :rules="apiValidate"
    >
      <Tabs name="edit-api-tabs" :animated="true">
        <TabPane label="基础信息" tab="edit-api-tabs">
          <FormItem label="接口名称" prop="name">
            <Input clearable v-model="apiForm.name" />
          </FormItem>
          <FormItem label="所属项目" prop="project">
            <div style="display: flex">
              <Select
                v-model="apiForm.project"
                @on-change="changeProjectOption"
              >
                <Option
                  v-for="item in projects"
                  :value="item.id"
                  :key="item.id"
                  :label="item.name"
                />
              </Select>
              <Button
                type="text"
                icon="ios-refresh"
                style="color: #2d8cf0"
                @click="getProjectNames"
                >刷新</Button
              >
            </div>
          </FormItem>
          <Row>
            <Col span="12">
              <FormItem label="运行环境">
                <Select
                  v-model="apiForm.environment"
                  clearable
                  placeholder="请先选择所属项目"
                >
                  <Option
                    v-for="item in environments"
                    :key="item.id"
                    :value="item.id"
                    :label="item.name"
                  >
                    <span>{{ item.name }}</span>
                    <span style="float: right; color: #ccc">{{
                      item.base_url
                    }}</span>
                  </Option>
                </Select>
              </FormItem>
            </Col>
            <Col span="12">
              <FormItem label="所属模块" prop="module">
                <SelectTree
                  v-model="apiForm.module"
                  :treeData="moduleSelectTreeData"
                ></SelectTree>
              </FormItem>
            </Col>
          </Row>
          <FormItem label="请求URL" prop="url">
            <Input clearable v-model="apiForm.url">
              <Select
                v-model="apiForm.method"
                slot="prepend"
                transfer
                style="width: 90px"
              >
                <Option value="GET" label="GET" />
                <Option value="POST" label="POST" />
                <Option value="PUT" label="PUT" />
                <Option value="PATCH" label="PATCH" />
                <Option value="DELETE" label="DELETE" />
                <Option value="OPTIONS" label="OPTIONS" />
                <Option value="HEAD" label="HEAD" />
              </Select>
            </Input>
          </FormItem>
          <FormItem label="备注">
            <Input
              type="textarea"
              clearable
              v-model="apiForm.remark"
              :rows="10"
            />
          </FormItem>
        </TabPane>
        <TabPane label="Headers参数" tab="edit-api-tabs">
          <div class="radio-group">
            <span class="radio-group-item">Content-Type</span>
            <RadioGroup
              v-model="contentType"
              @on-change="changeHeaderRadio('Content-Type', contentType)"
            >
              <Radio label="无" class="radio-group-item"></Radio>
              <Radio label="application/json" class="radio-group-item"></Radio>
              <Radio
                label="application/x-www-form-urlencoded"
                class="radio-group-item"
              ></Radio>
            </RadioGroup>
          </div>
          <div class="radio-group">
            <span class="radio-group-item">Authorization</span>
            <RadioGroup
              v-model="authorization"
              @on-change="changeHeaderRadio('Authorization', authorization)"
            >
              <Radio label="无" class="radio-group-item"></Radio>
              <Radio label="Bearer Token" class="radio-group-item"></Radio>
            </RadioGroup>
          </div>
          <JsonEditor
            v-model="apiForm.headers"
            jsonEditorId="editApiHeaders"
            style="height: 700px"
          ></JsonEditor>
        </TabPane>
        <TabPane :label="bodyTabPaneLabel" tab="edit-api-tabs">
          <FormItem label="参数类型" :label-width="80" prop="request_data_type">
            <RadioGroup v-model="apiForm.request_data_type">
              <Radio label="Json"></Radio>
              <Radio label="Form Data"></Radio>
            </RadioGroup>
          </FormItem>
          <JsonEditor
            v-model="apiForm.request_data"
            jsonEditorId="editApiRequestData"
            style="height: 700px"
          ></JsonEditor>
        </TabPane>
      </Tabs>
    </Form>

    <div slot="footer">
      <Button type="default" @click="handleEditApiCancel">取消</Button>
      <Button type="primary" @click="handleEditApiSubmit('apiForm')"
        >确定</Button
      >
    </div>
  </Modal>
</template>

<script>
import { updateApi } from "@/api/HttpAutoTestService/api";
import { getEnvNames } from "@/api/HttpAutoTestService/environment";
import { getProjectNames } from "@/api/HttpAutoTestService/project";
import { getModuleNames } from "@/api/HttpAutoTestService/module";
import JsonEditor from "_c/json-editor";
import SelectTree from "_c/select-tree";

export default {
  name: "api-edit",
  components: {
    JsonEditor,
    SelectTree,
  },
  props: {
    editApi: {
      type: Boolean,
      default: false,
    },
    api: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  computed: {
    showEditApiModal: {
      get() {
        return this.editApi;
      },
      set(val) {
        this.$emit("update:editApi", val);
        this.$emit("update:api", {});
      },
    },
    bodyTabPaneLabel() {
      return `Body参数（${this.apiForm.request_data_type})`;
    },
  },
  mounted() {
    this.getProjectNames();
  },
  watch: {
    api(val) {
      if (this.showEditApiModal) {
        this.apiForm = { ...val };
        this.changeProjectOption(this.apiForm.project);
      }
    },
  },
  data() {
    return {
      apiForm: {
        id: "",
        name: "",
        environment: "",
        project: "",
        module: "",
        url: "",
        method: "",
        headers: {},
        request_params: "",
        request_data_type: "Json",
        request_data: {},
        remark: "",
      },
      apiValidate: {
        name: [{ required: true, message: "请输入接口名称", trigger: "blur" }],
        project: [
          { required: true, message: "请选择所属项目", trigger: "change" },
        ],
        module: [
          { required: true, message: "请选择所属模块", trigger: "change" },
        ],
        url: [{ required: true, message: "请输入请求地址", trigger: "blur" }],
        request_data_type: [
          { required: true, message: "请选择参数类型", trigger: "change" },
        ],
      },
      projects: [],
      moduleSelectTreeData: [],
      environments: [],
      contentType: "application/json",
      authorization: "无",
    };
  },
  methods: {
    handleEditApiCancel() {
      this.showEditApiModal = false;
      this.apiForm = {
        id: "",
        name: "",
        environment: "",
        project: "",
        module: "",
        url: "",
        method: "",
        headers: {},
        request_params: "",
        request_data_type: "Json",
        request_data: {},
        remark: "",
      };
      this.$emit("initApiTable");
      this.$refs["apiForm"].resetFields();
    },
    handleEditApiSubmit(name) {
      this.$refs[name].validate((valid) => {
        if (valid) {
          let tempApi = { ...this.apiForm };
          tempApi.url = tempApi.url.trim();
          // url以/开始
          let index1 = tempApi.url.indexOf("/");
          if (index1 === 0) {
            let tempUrl = tempApi.url;
            tempApi.url = tempUrl.slice(index1 + 1);
          }
          // url中包含?,?之后的参数代表请求参数
          let index2 = tempApi.url.indexOf("?");
          if (index2 !== -1) {
            let tempUrl = tempApi.url;
            tempApi.url = tempUrl.slice(0, index2);
            tempApi.request_params = tempUrl.slice(index2 + 1);
          }

          if (tempApi.headers === "") {
            tempApi.headers = {};
          }

          if (tempApi.request_data === "") {
            tempApi.request_data = {};
          }

          if (!tempApi.environment) {
            tempApi.environment = "";
          }

          updateApi(tempApi)
            .then((res) => {
              if (res.status === 200) {
                this.$Message.info("修改成功");
                this.handleEditApiCancel();
              } else {
                this.$Message.error("修改失败");
              }
            })
            .catch((err) => {
              this.$Modal.error({
                title: "系统异常，请联系管理员……",
                content: JSON.stringify(err),
                closable: true,
              });
            });
        }
      });
    },
    getProjectNames() {
      getProjectNames()
        .then((res) => {
          this.projects = res.data;
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    changeProjectOption(val) {
      let data = {};
      if (val !== undefined) {
        data["project"] = val;
      }

      getEnvNames(data)
        .then((res) => {
          this.environments = res.data;
          // 获取该项目的所有运行环境
          this.projects.forEach((item) => {
            if (item.id === val) {
              let default_environment_id = item.default_environment_id;
              if (this.environments) {
                if (this.apiForm.environment) {
                  // 当前apiForm已经选择了运行环境
                  // 判断当前apiForm的运行环境是否在当前项目的运行环境中；如果在，则flag为true，否则为false
                  let flag = this.environments.some((item) => {
                    if (item.id === this.apiForm.environment) {
                      return true;
                    }
                  });

                  if (!flag) {
                    // 当apiForm的运行环境不在当前项目的运行环境中时，设置apiForm的运行环境为空
                    this.apiForm.environment = default_environment_id;
                  }
                } else {
                  // 当前apiForm没有选择运行环境，将项目的默认环境设置为apiForm的运行环境
                  this.apiForm.environment = default_environment_id;
                }
              }
            }
          });
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });

      getModuleNames(data)
        .then((res) => {
          let data = res.data;
          if (Array.isArray(data)) {
            let flag = data.some((item) => {
              return this.apiForm.module === item.id;
            });
            if (!flag) {
              // 接口的所属模块不存在于项目的模块中时，将接口的所属模块设置为空
              this.apiForm.module = "";
            }
          }

          let moduleSelectTreeData = data.map((item) => {
            return {
              value: item.id,
              title: item.name,
              parent: item.parent,
              expand: false,
            };
          });

          let arrayToTree = require("array-to-tree");
          this.moduleSelectTreeData = arrayToTree(moduleSelectTreeData, {
            parentProperty: "parent",
            childrenProperty: "children",
            customID: "value",
          });
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    // 更改请求头的Content-Type、Authorization内容
    changeHeaderRadio(property, value) {
      let headers = { ...this.apiForm.headers };
      if (value === "无") {
        delete headers[property];
      } else {
        if (property === "Content-Type") {
          headers["Content-Type"] = this.contentType;
        } else if (property === "Authorization") {
          headers["Authorization"] = this.authorization;
        }
      }
      this.apiForm.headers = headers;
    },
  },
};
</script>

<style scoped>
span {
  font-size: 14px;
  font-weight: bold;
  color: #464c5b;
}
.radio-group {
  display: flex;
  align-items: center;
}
.radio-group-item {
  margin: 0 20px 20px 0;
}
</style>

